package org.jsola.hr.web;

import org.apache.commons.io.FilenameUtils;
import org.jsola.common.FileKit;
import org.jsola.core.Page;
import org.jsola.core.Result;
import org.jsola.exception.ParamException;
import org.jsola.hr.common.ExcelKit;
import org.jsola.hr.constant.HrConstants;
import org.jsola.hr.dto.AttendPunchRecordAddDTO;
import org.jsola.hr.dto.AttendPunchRecordUpdateDTO;
import org.jsola.hr.dto.excel.AttendPunchRecordImportDTO;
import org.jsola.hr.exception.HrException;
import org.jsola.hr.query.AttendPunchRecordQuery;
import org.jsola.hr.service.IAttendPunchRecordService;
import org.jsola.hr.vo.AttendPunchRecordListVO;
import org.jsola.hr.vo.AttendPunchRecordVO;
import org.jsola.hr.vo.excel.AttendPunchRecordExportVO;
import org.jsola.hr.vo.excel.AttendanceSheetResultVO;
import org.jsola.hr.vo.excel.ParseResultVO;
import org.jsola.user.core.TokenUser;
import org.jsola.user.core.UserContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.Valid;
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.util.List;


/**
 * @author zhr
 */
@RestController("hrAttendPunchRecordController")
@RequestMapping(HrConstants.API_PATH + "/v1/attendPunchRecords")
public class AttendPunchRecordController implements IAttendPunchRecordControllerAPI {

    @Autowired
    private IAttendPunchRecordService attendPunchRecordService;

    @Override
    @PostMapping("/calculateSalaryByAttendPunch")
    public Result<AttendanceSheetResultVO> calculateSalaryByAttendPunch(@Valid @RequestBody AttendanceSheetResultVO attendanceSheetResultVO) {
        TokenUser tokenUser = UserContext.getUser();
        return Result.success(
                attendPunchRecordService.calculateSalaryByAttendPunch(attendanceSheetResultVO,tokenUser)
                );
    }

    @Override
    @PostMapping(value = "/parseExcelAttendanceSheet",headers = "content-type=multipart/form-data")
    public Result<AttendanceSheetResultVO> parseExcelAttendanceSheet(@RequestParam("file")MultipartFile file,@RequestParam("startCol") Integer startCol,@RequestParam("endCol")Integer endCol,@RequestParam("nameCol")Integer nameCol,@RequestParam("startRow")Integer startRow)  {
        TokenUser tokenUser = UserContext.getUser();
        if(file == null || file.isEmpty()){
            throw new HrException("上传文件失败");
        }
        return Result.success(
                attendPunchRecordService.parseExcelAttendanceSheet(file,tokenUser,startCol,endCol,nameCol,startRow)
        );
    }

    @Override
    @PostMapping
    public Result<AttendPunchRecordVO> save(@Valid @RequestBody AttendPunchRecordAddDTO attendPunchRecordAddDTO) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 新增考勤打卡记录权限校验

        return Result.success(
                attendPunchRecordService.save(attendPunchRecordAddDTO, tokenUser)
        );
    }


    @Override
    @PutMapping
    public Result<Integer> update(@Valid @RequestBody AttendPunchRecordUpdateDTO attendPunchRecordUpdateDTO) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 修改考勤打卡记录权限校验

        int count = attendPunchRecordService.update(attendPunchRecordUpdateDTO, tokenUser);
        if (count == 0) {
            throw new ParamException("更新失败，请刷新页面后重试");
        }
        return Result.success(count);
    }

    @Override
    @DeleteMapping(value = "/{attendPunchRecordId}")
    public Result<Integer> delete(@PathVariable String attendPunchRecordId) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 彻底删除考勤打卡记录权限校验

        int count = attendPunchRecordService.deleteByIds(tokenUser, attendPunchRecordId);
        if (count == 0) {
            throw new ParamException("删除失败，请刷新页面后重试");
        }
        return Result.success(count);
    }

    @Override
    @DeleteMapping
    public Result<Integer> deleteBatch(@RequestBody String[] attendPunchRecordIds) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 批量彻底删除考勤打卡记录权限校验

        int count = attendPunchRecordService.deleteByIds(tokenUser, attendPunchRecordIds);
        if (count == 0) {
            throw new ParamException("删除失败，请刷新页面后重试");
        }
        return Result.success(count);
    }

    @Override
    @GetMapping(value = "/{attendPunchRecordId}")
    public Result<AttendPunchRecordVO> findById(@PathVariable String attendPunchRecordId) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 查看考勤打卡记录权限校验

        return Result.success(
            attendPunchRecordService.selectById(attendPunchRecordId, tokenUser.getSiteId())
        );
    }

    @Override
    @GetMapping(value = "/listAll")
    public Result<List<AttendPunchRecordListVO>> listAll(@Valid AttendPunchRecordQuery attendPunchRecordQuery) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 查看考勤打卡记录权限校验

        return Result.success(
            attendPunchRecordService.select(attendPunchRecordQuery, tokenUser.getSiteId())
        );
    }


    @Override
    @GetMapping
    public Result<Page<AttendPunchRecordListVO>> page(@Valid AttendPunchRecordQuery attendPunchRecordQuery) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 查看项目权限校验

        return Result.success(
            attendPunchRecordService.selectPage(attendPunchRecordQuery, tokenUser.getSiteId())
        );
    }

    @Override
    @GetMapping("/export")
    public ResponseEntity<Resource> export(@Valid AttendPunchRecordQuery attendPunchRecordQuery) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 导出权限校验

        // 要导出的数据
        List<AttendPunchRecordExportVO> attendPunchRecordExportVOList = attendPunchRecordService.selectExportList(attendPunchRecordQuery,tokenUser.getSiteId());
        // 导出excel
        String excelFilePath = ExcelKit.exportExcel("attendPunchRecord", "考勤打卡记录", AttendPunchRecordExportVO.class, attendPunchRecordExportVOList);
        // 编码文件名，防止乱码
        String filenames = new String(FilenameUtils.getName(excelFilePath).getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
        return ResponseEntity.ok()
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=\"" + filenames + "\"")
                .header(HttpHeaders.CONTENT_TYPE,"application/vnd.ms-excel")
                .body(new FileSystemResource(excelFilePath));
    }

    @Override
    @PostMapping("/parse")
    public Result<List<ParseResultVO<AttendPunchRecordImportDTO>>> parseImportFile(@RequestParam("file") MultipartFile file, @RequestParam(required = false) Boolean success) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 导入解析excel权限校验

        // 临时保存到本地
        String excelFilePath = FileKit.saveFileToLocal(file,null,null,new String[]{"xls","xlsx"},null);
        File excelFile = new File(excelFilePath);
        HrException.isTrue(excelFile.exists(), "文件上传失败");
        return Result.success(
                attendPunchRecordService.parseImportFile(excelFile, success, tokenUser)
        );
    }

    @Override
    @PostMapping("/import")
    public Result<Integer> importFile(@RequestParam("file") MultipartFile file, @RequestParam(required = false) Boolean force) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 导入excel权限校验

        // 临时保存到本地
        String excelFilePath = FileKit.saveFileToLocal(file,null,null,new String[]{"xls","xlsx"},null);
        File excelFile = new File(excelFilePath);
        HrException.isTrue(excelFile.exists(), "文件上传失败");
        return Result.success(
                attendPunchRecordService.importFile(excelFile, tokenUser, force)
        );
    }

    @Override
    @GetMapping("/pageAttendPunchRecord")
    public Result<Page<AttendPunchRecordVO>> selectAttendPunchRecord(@Valid AttendPunchRecordQuery attendPunchRecordQuery) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 查看项目权限校验

        return Result.success(
                attendPunchRecordService.selectAttendPunchRecord(tokenUser, attendPunchRecordQuery)
        );
    }

    @Override
    @GetMapping("/selectAttendMonth")
    public Result<Page<AttendPunchRecordVO>> selectAttendMonth(@Valid AttendPunchRecordQuery attendPunchRecordQuery) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 查看项目权限校验

        return Result.success(
                attendPunchRecordService.selectAttendMonth(attendPunchRecordQuery, tokenUser)
        );
    }

    @Override
    @GetMapping("/selectAttendYearMonth")
    public Result<List<AttendPunchRecordVO>> selectAttendYearMonth(@Valid AttendPunchRecordQuery attendPunchRecordQuery) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 查看项目权限校验

        return Result.success(
                attendPunchRecordService.selectAttendYearMonth(attendPunchRecordQuery, tokenUser)
        );
    }


    @Override
    @GetMapping("/selectAttendByDay")
    public Result<Page<AttendPunchRecordVO>> selectAttendByDay(@Valid AttendPunchRecordQuery attendPunchRecordQuery) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 查看项目权限校验

        return Result.success(
                attendPunchRecordService.selectAttendByTime(attendPunchRecordQuery, tokenUser)
        );
    }

    @Override
    @GetMapping("/selectAttendByDayAndEmpId")
    public Result<List<AttendPunchRecordVO>> selectAttendByDayAndEmpId(@Valid AttendPunchRecordQuery attendPunchRecordQuery) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 查看项目权限校验

        return Result.success(
                attendPunchRecordService.selectAttendByDayAndEmpId(attendPunchRecordQuery, tokenUser)
        );
    }

    @Override
    @GetMapping("/exportAttendPunchRecord")
    public ResponseEntity<Resource> exportAttendPunchRecord(@Valid AttendPunchRecordQuery attendPunchRecordQuery) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 导出权限校验

        // 要导出的数据
        List<AttendPunchRecordVO> attend = attendPunchRecordService.exportAttendPunchRecord(tokenUser, attendPunchRecordQuery);
        attendPunchRecordService.setShouldDatCount(attend, attendPunchRecordQuery.getYear(),
                attendPunchRecordQuery.getMonth(), tokenUser);
        // 导出excel
        String excelFilePath = ExcelKit.exportExcel("attendPunchRecordUpdate", "考勤打卡记录", AttendPunchRecordVO.class, attend);
        // 编码文件名，防止乱码
        String filenames = new String(FilenameUtils.getName(excelFilePath).getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
        return ResponseEntity.ok()
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=\"" + filenames + "\"")
                .header(HttpHeaders.CONTENT_TYPE,"application/vnd.ms-excel")
                .body(new FileSystemResource(excelFilePath));
    }

    @Override
    @GetMapping("/exportAttendMonth")
    public ResponseEntity<Resource> exportAttendMonth(@Valid AttendPunchRecordQuery attendPunchRecordQuery) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 导出权限校验

        // 要导出的数据
        List<AttendPunchRecordVO> attend = attendPunchRecordService.exportAttendMonth(attendPunchRecordQuery, tokenUser);
        // 导出excel
        String excelFilePath = ExcelKit.exportExcel("attendMonth", "个人月报表", AttendPunchRecordExportVO.class, attend);
        // 编码文件名，防止乱码
        String filenames = new String(FilenameUtils.getName(excelFilePath).getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
        return ResponseEntity.ok()
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=\"" + filenames + "\"")
                .header(HttpHeaders.CONTENT_TYPE,"application/vnd.ms-excel")
                .body(new FileSystemResource(excelFilePath));
    }

    @Override
    @GetMapping("/exportAttendByDay")
    public ResponseEntity<Resource> exportAttendByDay(@Valid AttendPunchRecordQuery attendPunchRecordQuery) {
        TokenUser tokenUser = UserContext.getUser();
        // todo 导出权限校验

        // 要导出的数据
        String enName = "attendByDay";
        List<AttendPunchRecordVO> attend = attendPunchRecordService.exportAttendByTime(attendPunchRecordQuery, tokenUser);
        if (attendPunchRecordQuery.getIsError() != null && attendPunchRecordQuery.getIsError()) {
            // 只导出异常数据
            attend = attendPunchRecordService.filtration(attend);
            enName = "attendByDayError";
        }
        attendPunchRecordService.showExportTime(attend);
        // 导出excel
        String excelFilePath = ExcelKit.exportExcel(enName, "每日考勤打卡记录", AttendPunchRecordExportVO.class, attend);
        // 编码文件名，防止乱码
        String filenames = new String(FilenameUtils.getName(excelFilePath).getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
        return ResponseEntity.ok()
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=\"" + filenames + "\"")
                .header(HttpHeaders.CONTENT_TYPE,"application/vnd.ms-excel")
                .body(new FileSystemResource(excelFilePath));
    }
}

